package com.jeesite.modules.dataScreen.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.jeesite.modules.dataScreen.constants.SsmContactScope;
import com.jeesite.modules.dataScreen.constants.SsmContactTypeEnum;
import com.jeesite.modules.dataScreen.dao.SsmContactDao;
import com.jeesite.modules.dataScreen.entity.SsmContact;
import com.jeesite.modules.dataScreen.service.SsmContactService;
import com.jeesite.modules.dataScreen.web.dto.SsmContactUpdateDto;
import com.jeesite.modules.dataScreen.web.vo.alarm.HotConcernCurrentVo;
import com.jeesite.modules.dataScreen.web.vo.ssmContact.SsmContactTreeVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 通信录(SsmContact)表服务实现类
 *
 * @author makejava
 * @since 2024-08-26 14:41:14
 */
@Slf4j
@Service("ssmContactService")
@DS("theme-db")
public class SsmContactServiceImpl extends ServiceImpl<SsmContactDao, SsmContact> implements SsmContactService {


    LoadingCache<String, List<SsmContact>> cache = CacheBuilder.newBuilder()
            // 设置并发级别为8，并发级别是指可以同时写缓存的线程数
            .concurrencyLevel(4)
            // 设置写缓存后过期时间
            .expireAfterWrite(180, TimeUnit.SECONDS)
            // 设置缓存容器的初始容量
            .initialCapacity(2)
            // 设置缓存最大容量,超过最大容量之后就会按照LRU最近虽少使用算法来移除缓存项
            .maximumSize(2)
            // 设置要统计缓存的命中率
            .recordStats()
            //当获取缓存不存在时, 默认执行
            .build(new CacheLoader<String, List<SsmContact>>() {
                @Override
                public List<SsmContact> load(String key) {
                    return getBaseMapper().selectList(null);
                }
            });

    @Override
    public List<SsmContactTreeVo> buildTree() {
        List<SsmContact> ssmContacts = all();
        Map<SsmContactTypeEnum, List<SsmContact>> listMap = ssmContacts.stream().collect(Collectors.groupingBy(SsmContact::getType));
        List<SsmContactTreeVo> result = new ArrayList<>();
        for (SsmContactTypeEnum value : SsmContactTypeEnum.values()) {

            //通过分类处理数据
            SsmContactTreeVo vo = new SsmContactTreeVo();
            result.add(vo);
            vo.setCode(value.name());
            vo.setName(value.getText());
            if (value != SsmContactTypeEnum.HY_CONTACT) {
                List<SsmContact> contacts = listMap.get(value);
                List<SsmContactTreeVo.UserItem> userItems = new ArrayList<>();
                if (!CollUtil.isEmpty(contacts)) {
                    for (SsmContact contact : contacts) {
                        SsmContactTreeVo.UserItem userItem = new SsmContactTreeVo.UserItem();
                        userItems.add(userItem);
                        userItem.setJobName(contact.getJobName());
                        userItem.setId(contact.getId());
                        userItem.setName(contact.getName());
                        userItem.setTel(contact.getTel());
                    }
                }
                vo.setUsers(userItems);
                continue;
            }
            listMap.get(value);
            vo.setCode(null);
            if (CollUtil.isNotEmpty(ssmContacts)) {
                //地区分类数据
                List<SsmContactTreeVo.TypeItem> typeItems = new ArrayList<>();
                vo.setChildren(typeItems);
                Map<String, List<SsmContact>> scopeMap = ssmContacts.stream().collect(Collectors.groupingBy(SsmContact::getScope));
                List<String> scopes = SsmContactScope.scopes();
                for (String scope : scopes) {
                    SsmContactTreeVo.TypeItem typeItem = new SsmContactTreeVo.TypeItem();
                    typeItems.add(typeItem);
                    typeItem.setName(scope);
                    List<SsmContact> scopeList = scopeMap.get(scope);
                    if (CollUtil.isNotEmpty(scopeList)) {
                        //单位分类数据
                        Map<String, List<SsmContact>> unitMap = scopeList.stream().collect(Collectors.groupingBy(SsmContact::getUnitName));
                        for (Map.Entry<String, List<SsmContact>> entry : unitMap.entrySet()) {
                            SsmContactTreeVo.UnitItem unitItem = new SsmContactTreeVo.UnitItem();
                            typeItem.getChildren().add(unitItem);
                            unitItem.setName(entry.getKey());
                            //部门分类数据
                            Map<String, List<SsmContact>> deptMap = entry.getValue().stream().collect(Collectors.groupingBy(SsmContact::getDeptName));
                            for (Map.Entry<String, List<SsmContact>> deptEntry : deptMap.entrySet()) {
                                SsmContactTreeVo.DeptItem deptItem = new SsmContactTreeVo.DeptItem();
                                unitItem.getChildren().add(deptItem);
                                deptItem.setName(deptEntry.getKey());
                                for (SsmContact contact : deptEntry.getValue()) {
                                    SsmContactTreeVo.UserItem userItem = new SsmContactTreeVo.UserItem();
                                    deptItem.getUsers().add(userItem);
                                    userItem.setJobName(contact.getJobName());
                                    userItem.setId(contact.getId());
                                    userItem.setName(contact.getName());
                                    userItem.setTel(contact.getTel());
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

    @Override
    public void updateSsmContact(SsmContactUpdateDto dto) {
        LambdaUpdateWrapper<SsmContact> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(SsmContact::getId, dto.getUserIds());
        updateWrapper.set(SsmContact::getType, dto.getCode());
        updateWrapper.set(SsmContact::getUpdateAt, DateUtil.date());
        this.update(updateWrapper);
        refreshCache();
        log.info("updateSsmContact: to > {},userIds:{}", dto.getCode(), dto.getUserIds());
    }

    @Override
    public void ejectment(Integer id) {
        LambdaUpdateWrapper<SsmContact> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SsmContact::getId, id);
        updateWrapper.set(SsmContact::getUpdateAt, DateUtil.date());
        updateWrapper.set(SsmContact::getType, SsmContactTypeEnum.HY_CONTACT);
        this.update(updateWrapper);
        refreshCache();
        log.info("removeGroup: userIds:{}", id);
    }

    @Override
    public List<SsmContact> all() {
        try {
            return cache.get("");
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<SsmContact> findPhoneByIds(List<Integer> id) {
        return all().stream().filter(e -> id.contains(e.getId())).collect(Collectors.toList());
    }

    private void refreshCache() {
        cache.refresh("");
    }

}

